/**
@author		Jong Min, Lee
@date		  10/01/2014
@breif		series class and producer class 

copyright(c) Tae Young Soft. All right reserved. 2014
*/
#pragma once

#include <vector>

#include "Taurus_Util/Macros.h"
#include "Taurus_DcmData/Defines.h"

//forward declarations
class CDcmSeries;
class CInstance;
class CStudy;

/**
@brief		proxy class for dicom series
*/
class TAURUS_DCMDATA_EXPORT CSeries
{
private:
  /**
  @brief		default constructor
  */
  CSeries();

  DISALLOW_COPY_AND_ASSIGN(CSeries);

public:
  friend class CSeriesProducer;

  /**
  @brief		destructor
  */
  ~CSeries();

  /**
  @brief		access parent study
  @return		pointer to parent study if series has it, NULL if not
  */
  inline CStudy* getParent() const
  {
    return m_theParent;
  }

  /**
  @brief		set parent study
  @param		parent pointer to study to be parent
  */
  inline void setParent(CStudy* parent)
  {
    m_theParent = parent;
  }

  /**
  @brief		get modality
  @return		null-terminated string represents modality
  */
  const TCHAR* getModality() const;

  /**
  @brief		check whether series is none image series or not
  @return		TRUE if series is none image, FALSE if not
  */
  BOOL isNoneImage() const;

  /**
  @brief		get the number instance belong to series
  @return		the number of instances belong to series
  */
  inline unsigned int getNumInstances() const
  {
    return m_theInstances.size();
  }

  /**
  @brief		access to an instance
  @param		index the index number of instance to be accessed
  @return		pointer to instance if found, NULL if not
  */
  const CInstance* getInstance(const unsigned int index) const;

  CInstance* getInstance(const unsigned int index);

private:
  /**
  @brief		initialize series
  */
  void init();

  /**
  @brief		destroy series. this function should be only used in destructor
  */
  void destroy();

  /**
  @brief		remove all instances
  */
  void removeAllInstances();

private:
  //pointer to parent study
  CStudy* m_theParent;

  //pointer to dcm series
  CDcmSeries* m_theDcmSeries;

  std::vector<CInstance*> m_theInstances;
};

/**
@brief		series producer class
*/
class TAURUS_DCMDATA_EXPORT CSeriesProducer
{
public:
  /**
  @brief		craeta a new series
  @param		dcmSeries pointer to dcm series to be based
  @param    parent pointer to study to be parent
  @param    outSeries variable in which pointer to new series is stored
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  static DWORD produce(CDcmSeries* dcmSeries,
                       CStudy* parent,
                       CSeries*& outSeries);

  /**
  @brief		create a new series
  @param		dcmSeries pointer to dcm series to be base
  @param    instances pointers to instances to be belong to series
  @param    numInstance the number of instances to be belong to series
  @param    parent pointer to study to be parent
  @param    outSeries variable in which new series is stored
  @return		
  */
  static DWORD produce(CDcmSeries* dcmSeries,
                       CInstance** instances,
                       const unsigned int numInstances,
                       CStudy* parent,
                       CSeries*& outSeries);

private:
  /**
  @brief		attach dicom series to series. this function only initialize data related with series
  @param		series pointer to series
  @param    dcmSeries pointer to dicom series to be attached
  @param    parent pointer to study to be parent
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  static DWORD attachDcmSeries(CSeries* series,
                               CDcmSeries* dcmSeries,
                               CStudy* parent);
};